// audioManager.js - 音频管理服务
// 提供单例模式的音频管理器
let instance = null;
const FileUtils = require('../utils/fileUtils');
const { getWordDataManager } = require('./wordDataManager');

class AudioManager {
  constructor() {
    this.audioContext = null;
    this.isPlaying = false;
    this.currentAudioUrl = '';
    this.statusChangeCallbacks = [];
    this.currentPlaybackSpeed = 1.0; // 当前播放速度，默认1.0
    
    // 循环播放相关变量
    this.isLoopEnabled = false;
    this.loopCount = null; // null表示无限循环
    this.loopInterval = 2000; // 循环间隔，默认2秒
    this.currentLoopIndex = 0;
    this.loopTimer = null;
    
    // 文件工具类实例
    this.fileUtils = new FileUtils();
    // 初始化时清理过期缓存
    this.fileUtils.cleanupCache();
  }
  
  /**
   * 获取音频管理器的单例实例
   * @returns {AudioManager} 音频管理器实例
   */
  static getInstance() {
    if (!instance) {
      instance = new AudioManager();
    }
    return instance;
  }
  
  /**
   * 初始化音频上下文
   */
  initAudioContext() {
    if (!this.audioContext) {
      this.audioContext = wx.createInnerAudioContext();
      this.setupAudioEvents();
    }
    return this.audioContext;
  }

  /**
   * 添加状态变化回调函数
   * @param {Function} callback - 状态变化时的回调函数
   */
  addStatusChangeCallback(callback) {
    if (typeof callback === 'function' && !this.statusChangeCallbacks.includes(callback)) {
      this.statusChangeCallbacks.push(callback);
    }
  }

  /**
   * 移除状态变化回调函数
   * @param {Function} callback - 要移除的回调函数
   */
  removeStatusChangeCallback(callback) {
    const index = this.statusChangeCallbacks.indexOf(callback);
    if (index > -1) {
      this.statusChangeCallbacks.splice(index, 1);
    }
  }

  /**
   * 触发状态变化回调
   */
  triggerStatusChangeCallbacks() {
    const status = this.getStatus();
    this.statusChangeCallbacks.forEach(callback => {
      try {
        callback(status);
      } catch (error) {
        console.error('Status change callback error:', error);
      }
    });
  }

  /**
   * 设置音频上下文事件监听
   */
  setupAudioEvents() {
    if (!this.audioContext) return;

    // 清除已有的事件监听器，防止重复监听
    this.audioContext.offPlay();
    this.audioContext.offEnded();
    this.audioContext.offError();
    this.audioContext.offStop();

    this.audioContext.onPlay(() => {
      console.log('音频开始播放');
      this.isPlaying = true;
      this.triggerStatusChangeCallbacks();
    });

    this.audioContext.onEnded(() => {
      console.log('音频播放结束');
      
      // 检查是否启用了循环播放
      if (this.isLoopEnabled && this.currentAudioUrl) {
        // 检查是否达到了循环次数限制
        if (this.loopCount !== null) {
          this.currentLoopIndex++;
          if (this.currentLoopIndex >= this.loopCount) {
            // 达到循环次数限制，停止循环
            this.isPlaying = false;
            this.triggerStatusChangeCallbacks();
            return;
          }
        }
        
        // 设置延时后再次播放
        this.loopTimer = setTimeout(() => {
          try {
            this.audioContext.play().catch(error => {
              console.error('循环播放失败:', error);
              this.isPlaying = false;
              this.triggerStatusChangeCallbacks();
            });
          } catch (error) {
            console.error('循环播放调用失败:', error);
            this.isPlaying = false;
            this.triggerStatusChangeCallbacks();
          }
        }, this.loopInterval);
        
        // 保持播放状态
        this.isPlaying = true;
      } else {
        // 对于倍速播放，添加一个小延时确保音频完整播放
        if (this.currentPlaybackSpeed && Math.abs(this.currentPlaybackSpeed - 1.0) > 0.1) {
          setTimeout(() => {
            this.isPlaying = false;
            this.triggerStatusChangeCallbacks();
          }, 100); // 100毫秒延时，确保倍速播放的音频末尾完整播放
        } else {
          this.isPlaying = false;
          this.triggerStatusChangeCallbacks();
        }
      }
    });

    this.audioContext.onError((error) => {
      console.error('音频播放错误:', error);
      this.isPlaying = false;
      this.triggerStatusChangeCallbacks();
      wx.showToast({
        title: '播放失败',
        icon: 'none',
        duration: 2000
      });
    });

    this.audioContext.onStop(() => {
      console.log('音频播放停止');
      this.isPlaying = false;
      // 清除循环计时器
      if (this.loopTimer) {
        clearTimeout(this.loopTimer);
        this.loopTimer = null;
      }
      this.triggerStatusChangeCallbacks();
    });
  }

  /**
   * 设置循环播放参数
   * @param {boolean} enabled - 是否启用循环播放
   * @param {number|null} count - 循环次数，null表示无限循环
   * @param {number} interval - 循环间隔（毫秒）
   */
  setLoopSettings(enabled, count = null, interval = 2000) {
    this.isLoopEnabled = enabled;
    this.loopCount = count;
    this.loopInterval = interval * 1000; // 转换为毫秒
    this.currentLoopIndex = 0;
    
    // 如果禁用循环，清除计时器
    if (!enabled && this.loopTimer) {
      clearTimeout(this.loopTimer);
      this.loopTimer = null;
    }
  }
  
  /**
   * 播放发音
   * @param {Object} wordObj - 单词对象
   * @param {number} speed - 播放速度
   * @param {string} type - 发音类型
   * @returns {Promise} 播放Promise
   */
  async playPronunciation(wordObj, speed, type) {
    // 检查是否提供了单词对象
    if (!wordObj) {
      console.error('未提供单词对象');
      return Promise.reject(new Error('未提供单词对象'));
    }
    
    // 检查是否需要丰富单词数据
    const wordDataManager = getWordDataManager();
    // 检查单词是否已经丰富
    const isEnriched = wordDataManager._isWordEnriched(wordObj);
    
    if (!isEnriched) {
      try {
        // 显示加载提示
        wx.showLoading({
          title: '正在加载单词信息...',
        });
        
        // 丰富单词数据
        await wordDataManager.enrichWords([wordObj.id]);
        console.log(`单词 ${wordObj.english} 已成功丰富`);
      } catch (error) {
        console.warn('单词丰富失败，但仍尝试播放:', error);
      } finally {
        // 隐藏加载提示
        wx.hideLoading();
      }
    }
    
    // 根据单词对象和发音类型获取音频URL
    const audioUrl = this.getAudioUrl(wordObj, type);
    
    if (!audioUrl) {
      console.error(`未找到单词 ${wordObj.english} 的${type}发音音频资源`);
      wx.showToast({
        title: '未找到音频资源',
        icon: 'none',
        duration: 2000
      });
      return Promise.reject(new Error('未找到音频资源'));
    }
    
    // 确保音频上下文存在
    this.initAudioContext();

    // 停止当前正在播放的音频和循环计时器
    if (this.isPlaying) {
      this.stopPronunciation();
    }
    
    if (this.loopTimer) {
      clearTimeout(this.loopTimer);
      this.loopTimer = null;
    }

    // 设置音频属性
    this.audioContext.src = audioUrl;
    this.audioContext.playbackRate = speed;
    this.audioContext.volume = 1.0;

    // 存储当前播放速度，用于onTimeUpdate事件中判断
    this.currentPlaybackSpeed = speed;
    
    // 从wordDataManager获取循环播放设置并应用
    const pronunciationSettings = wordDataManager.getPronunciationSettings();
    const loopPlay = pronunciationSettings.loopPlay || false;
    const loopCount = pronunciationSettings.loopCount !== undefined ? pronunciationSettings.loopCount : null;
    const loopInterval = pronunciationSettings.loopInterval !== undefined ? pronunciationSettings.loopInterval : 2;
    
    // 应用循环播放设置
    this.setLoopSettings(loopPlay, loopCount, loopInterval);
    
    // 重置循环索引
    this.currentLoopIndex = 0;

    // 返回播放Promise
    return new Promise((resolve, reject) => {
      try {
        // 直接尝试播放音频，不再使用预加载机制
        const playPromise = this.audioContext.play();

        // 检查是否返回Promise
        if (playPromise && typeof playPromise.then === 'function') {
          playPromise.then(() => {
            this.isPlaying = true;
            this.currentAudioUrl = audioUrl;
            console.log(`开始播放: ${wordObj.english} (${type}, ${speed}x)`);
            resolve();
          }).catch((error) => {
            console.error('播放失败:', error);
            this.isPlaying = false;
            reject(error);
          });
        } else {
          // 如果不是Promise，直接设置状态
          this.isPlaying = true;
          this.currentAudioUrl = audioUrl;
          console.log(`开始播放: ${wordObj.english} (${type}, ${speed}x)`);
          resolve();
        }
      } catch (error) {
        console.error('播放调用失败:', error);
        this.isPlaying = false;
        reject(error);
      }
    });
  }

  /**
   * 播放文本转语音
   * @param {string} text - 要转换为语音的文本
   * @param {number} speed - 播放速度
   * @returns {Promise} 播放Promise
   */
  async playTextToSpeech(text, speed = 1.0, accent = 'zh') {
    // 确保音频上下文存在
    this.initAudioContext();

    // 停止当前正在播放的音频和循环计时器
    if (this.isPlaying) {
      this.stopPronunciation();
    }
    
    if (this.loopTimer) {
      clearTimeout(this.loopTimer);
      this.loopTimer = null;
    }

    // 存储当前播放速度
    this.currentPlaybackSpeed = speed;
    
    // 重置循环索引
    this.currentLoopIndex = 0;

    try {
      // 生成缓存文件名
      const cacheFileName = this.fileUtils.generateCacheFileName(text);
      
      // 检查本地是否已存在缓存文件
      const fileExists = await this.fileUtils.checkFileExists(cacheFileName);
      
      let audioFilePath;
      
      if (fileExists) {
        // 如果文件存在，直接使用本地文件
        audioFilePath = this.fileUtils.getCacheFilePath(cacheFileName);
        console.log(`使用本地缓存文件: ${audioFilePath}`);
      } else {
        // 如果文件不存在，获取音频URL并下载
        const audioUrl = await this.fetchAudioUrl(text, accent);
        audioFilePath = await this.fileUtils.downloadFile(audioUrl, cacheFileName);
      }
      
      // 返回播放Promise
      return this.playLocalAudio(audioFilePath, text, speed);
    } catch (error) {
      console.error('语音合成播放失败:', error);
      this.isPlaying = false;
      throw error;
    }
  }

  /**
   * 从TTS服务获取音频URL
   * @param {string} text - 要转换为语音的文本
   * @param {string} accent - 发音口音，默认'zh'。可选：'zh'、'en'
   * @returns {Promise<string>} 音频URL
   */
  fetchAudioUrl(text, accent = 'zh') {
    return new Promise((resolve, reject) => {
      try {
        // 使用entts.com的TTS服务
        const ttsUrl = 'https://api.entts.com/post/';
        const requestBody = `content=${encodeURIComponent(text)}&accent=${accent}&speed=-2`;
        
        // 发送POST请求获取音频URL
        wx.request({
          url: ttsUrl,
          method: 'POST',
          header: {
            'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'content-type': 'application/x-www-form-urlencoded'
          },
          data: requestBody,
          success: (res) => {
            // 解析HTML响应，提取音频URL
            const htmlResponse = res.data;
            
            // 使用正则表达式提取<source>标签中的src属性
            const srcMatch = htmlResponse.match(/<source\s+src="([^"]+)"/);
            
            if (srcMatch && srcMatch[1]) {
              const audioUrl = srcMatch[1];
              console.log('提取到音频URL:', audioUrl);
              resolve(audioUrl);
            } else {
              console.error('无法从响应中提取音频URL');
              reject(new Error('无法从响应中提取音频URL'));
            }
          },
          fail: (error) => {
            console.error('TTS服务请求失败:', error);
            reject(error);
          }
        });
      } catch (error) {
        console.error('获取音频URL失败:', error);
        reject(error);
      }
    });
  }

  /**
   * 播放本地音频文件
   * @param {string} filePath - 本地文件路径
   * @param {string} text - 文本内容
   * @param {number} speed - 播放速度
   * @returns {Promise} 播放Promise
   */
  playLocalAudio(filePath, text, speed) {
    return new Promise((resolve, reject) => {
      try {
        // 设置音频源
        this.audioContext.src = filePath;
        
        // 设置播放速度
        if (this.audioContext.playbackRate !== undefined) {
          this.audioContext.playbackRate = speed;
        }
        
        // 设置音量
        this.audioContext.volume = 1.0;
        
        // 设置循环播放为false
        this.audioContext.loop = false;
        
        // 设置事件回调函数
        const onPlayHandler = () => {
          console.log(`开始播放语音合成: ${text}`);
          this.isPlaying = true;
          this.currentAudioUrl = filePath;
          this.triggerStatusChangeCallbacks();
          resolve();
        };
        
        const onEndedHandler = () => {
          this.isPlaying = false;
          this.triggerStatusChangeCallbacks();
          // 移除临时事件监听器
          this.audioContext.offPlay(onPlayHandler);
          this.audioContext.offEnded(onEndedHandler);
          this.audioContext.offError(onErrorHandler);
        };
        
        const onErrorHandler = (error) => {
          console.error('语音合成播放失败:', error);
          this.isPlaying = false;
          this.triggerStatusChangeCallbacks();
          // 移除临时事件监听器
          this.audioContext.offPlay(onPlayHandler);
          this.audioContext.offEnded(onEndedHandler);
          this.audioContext.offError(onErrorHandler);
          reject(error);
        };
        
        // 添加临时事件监听器
        this.audioContext.onPlay(onPlayHandler);
        this.audioContext.onEnded(onEndedHandler);
        this.audioContext.onError(onErrorHandler);
        
        // 开始播放
        this.audioContext.play();
      } catch (error) {
        console.error('播放本地音频失败:', error);
        this.isPlaying = false;
        reject(error);
      }
    });
  }

  /**
   * 停止发音播放
   */
  stopPronunciation() {
    if (this.audioContext && this.isPlaying) {
      this.audioContext.stop();
      this.isPlaying = false;
      // 清除循环计时器
      if (this.loopTimer) {
        clearTimeout(this.loopTimer);
        this.loopTimer = null;
      }
      console.log('停止播放音频');
    }
    
    // 同时尝试停止背景音频管理器
    try {
      const backgroundAudioManager = wx.getBackgroundAudioManager ? wx.getBackgroundAudioManager() : null;
      if (backgroundAudioManager && backgroundAudioManager.stop) {
        backgroundAudioManager.stop();
      }
    } catch (error) {
      console.error('停止背景音频失败:', error);
    }
  }

  /**
   * 获取单词音频URL
   * @param {Object} currentWord - 当前单词对象
   * @param {string} type - 发音类型
   * @returns {string|null} 音频URL或null
   */
  getAudioUrl(currentWord, type) {
    // 检查currentWord是否有pronunciation字段和audio子字段
    if (currentWord && currentWord.pronunciation && currentWord.pronunciation.audio) {
      const audioUrls = currentWord.pronunciation.audio;

      // 根据类型返回对应的音频URL
      if (type === 'american' && audioUrls.us) {
        return audioUrls.us;
      } else if (type === 'british' && audioUrls.uk) {
        return audioUrls.uk;
      }
    }

    // 如果没有找到音频URL，记录警告并返回null
    console.warn(`未找到单词 ${currentWord?.word} 的${type}发音音频资源`);
    return null;
  }

  /**
   * 销毁音频上下文
   */
  destroy() {
    // 清理音频上下文
    if (this.audioContext) {
      this.audioContext.destroy();
      this.audioContext = null;
      this.isPlaying = false;
      this.currentAudioUrl = '';
    }
    
    // 清理循环计时器
    if (this.loopTimer) {
      clearTimeout(this.loopTimer);
      this.loopTimer = null;
    }
  }

  /**
   * 获取音频管理器状态
   */
  getStatus() {
    return {
      isPlaying: this.isPlaying,
      currentAudioUrl: this.currentAudioUrl,
      isLoopEnabled: this.isLoopEnabled,
      loopCount: this.loopCount,
      loopInterval: this.loopInterval,
      currentLoopIndex: this.currentLoopIndex
    };
  }
}

// 导出类和单例实例
module.exports = {
  AudioManager,
  getInstance: AudioManager.getInstance
};

// 同时设置默认导出为单例实例
module.exports.default = AudioManager.getInstance();